home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Deutsche Edition 1
/
Deutsche Edition 1.iso
/
amok
/
021-030
/
amok25
/
microtimer
/
microtimer.mod
< prev
next >
Wrap
Text File
|
1993-11-04
|
3KB
|
132 lines
(*
:Program. MicroTimer.mod
:Author. Volker Rudolph
:Address. Medicusstr. 31 / 6750 Kaiserslautern
:Phone. 0631/17160
:Copyright. PD
:Language. Modula-II
:Translator. M2Amiga 3.2d
:History. V1.1 V. Rudolph 24.4.1989
:Contents. MicroTimer ermöglicht sehr präzise Zeitmessungen.
*)
IMPLEMENTATION MODULE MicroTimer;
FROM Arts IMPORT Assert, TermProcedure;
FROM Hardware IMPORT CiaCraFlagSet,CiaCraFlags,CiaCrbFlagSet,CiaCrbFlags,
UByte, ciab;
FROM SYSTEM IMPORT ADR;
CONST
MAXINT = MAX(LONGINT);
(* Umrechung CIA-Ticks in Mikrosekunden. *)
(* Sollte eigentlich Systemtakt / 10 sein (0.716), liefert aber dann *)
(* eine falsche Zeit. Durch ausprobieren habe ich diesen besseren *)
(* Wert gefunden *)
TickToMicro = 0.7088;
(* Maximale Anzahl von Ticks bis zum LONGINT-Overflow *)
maxTicks = LONGINT(LONGREAL(MAXINT) * TickToMicro);
TYPE
(* Konversion: Vier einzelne Bytes in LONGINT *)
Convert = RECORD
CASE :BOOLEAN OF
TRUE: byte3:UByte;
byte2:UByte;
byte1:UByte;
byte0:UByte;
|FALSE:ticks:LONGINT;
END; (* CASE *)
END;
VAR
running:BOOLEAN;
(* TermProcedure : Beide Timer stoppen *)
PROCEDURE StopIt;
BEGIN
IF running THEN
running := FALSE;
ciab.cra := CiaCraFlagSet{};
ciab.crb := CiaCrbFlagSet{};
END; (* IF *)
END StopIt;
(* Timer starten *)
PROCEDURE StartTimer;
VAR
inUse:BOOLEAN;
BEGIN
inUse := (crbStart IN ciab.crb) OR (craStart IN ciab.cra);
Assert(NOT inUse, ADR("MicroTimer : Timer already in use"));
running := TRUE;
WITH ciab DO
(* Beide Timer auf MAXINT stellen *)
tbhi := 07FH;
tblo := 0FFH;
tahi := 0FFH;
talo := 0FFH;
(* Timer b mit Timer a koppeln und Startzeit von Timer b laden *)
crb := CiaCrbFlagSet{crbLoad,crbStart,crbRunmode,crbInmode1};
(* Timer a mit Startzeit laden und starten *)
cra := CiaCraFlagSet{craLoad,craStart};
END; (* WITH *)
END StartTimer;
(* Zeit auslesen während Timer läuft *)
PROCEDURE LookTimer(VAR micros:LONGINT);
VAR
conv:Convert;
ok:BOOLEAN;
BEGIN
WITH ciab DO
WITH conv DO
(* Zeit auslesen, bei Fehler wiederholen bis ok *)
REPEAT
byte3 := tbhi;
byte2 := tblo;
ok := (tbhi = byte3);
byte1 := tahi;
ok := ok AND (tblo = byte2);
byte0 := talo;
ok := ok AND (tahi = byte1);
UNTIL ok;
END; (* WITH *)
END; (* WITH *)
(* Verstrichene Zeit berechnen *)
micros := (MAXINT - conv.ticks);
(* Ist maximale Meßdauer überschritten ? *)
IF micros > maxTicks THEN
micros := 0;
ELSE
(* In Microsekunden umrechnen *)
micros := LONGINT(LONGREAL(micros) / TickToMicro);
END; (* IF *)
END LookTimer;
(* Timer stoppen *)
PROCEDURE StopTimer(VAR micros:LONGINT);
BEGIN
StopIt;
LookTimer(micros);
END StopTimer;
(* Mikrosekunden in Minuten, Sekunden und restliche Micros umrechnen *)
PROCEDURE MicrosToTime(VAR minutes, seconds:CARDINAL;VAR micros:LONGINT;
inputMicros:LONGINT);
BEGIN
minutes := inputMicros DIV (1000000 * 60);
seconds := (inputMicros DIV 1000000) MOD 60;
micros := inputMicros MOD 1000000;
END MicrosToTime;
BEGIN
running := FALSE;
TermProcedure(StopIt);
END MicroTimer.